#pragma once

#include "Ribbonview.h"
#include "RibbonInfo.h"
#include "PropertyReader.h"
#include <memory>
#include <map>
#include <sstream>

using namespace std;
using namespace std::tr1;

#define RIBBONRESULTVIEW_WNDCLASS L"RIBBONRESULTVIEW"

class ICloseEvent
{
public:
	virtual void OnClose() = 0;
};

class CRibbonOutputWindow;
LRESULT CALLBACK RibbonResultsWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

class CRibbonResultView : public CRibbonView
{
	friend LRESULT CALLBACK RibbonResultsWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

private:
	CPropertyReader m_propertyReader; 
	CRibbonOutputWindow *m_pRibbonOutputWindow;
	shared_ptr<CRibbonInfo> m_ribbonInfo;
	basic_stringstream<wchar_t> m_initText;
	map<UI_COMMANDTYPE, LPCWSTR> m_commandTypeMap;
	HWND m_hWnd;
	vector<ICloseEvent *> m_closeHandlers;
	static CRibbonResultView *s_pRibbonResultView;
	CComPtr<IStream> m_stateStream;
	CComPtr<IUIRibbon> m_ribbon;

	LPCWSTR TranslateType(UI_COMMANDTYPE typeID);
	static LPCWSTR GetVerbName(UI_EXECUTIONVERB verb);

	bool m_bUseSetValues;
	wstring m_setStringValue;
	double m_setNumericValue;
	bool m_setBooleanValue;

public:
	void AppendText(const wstring &text);
	HRESULT SetPropertyValues(REFPROPERTYKEY key, PROPVARIANT *newValue);

	STDMETHOD(OnCreateUICommand)(UINT32 nCmdID, __in UI_COMMANDTYPE typeID, __deref_out IUICommandHandler** ppCommandHandler);
	STDMETHOD(OnViewChanged)(UINT32 nViewID, __in UI_VIEWTYPE typeID, __in IUnknown* pView, UI_VIEWVERB verb, INT32 uReasonCode);  
    
	STDMETHOD(Execute)(UINT nCmdID,
		UI_EXECUTIONVERB verb, 
		__in_opt const PROPERTYKEY* key,
		__in_opt const PROPVARIANT* ppropvarValue,
		__in_opt IUISimplePropertySet* pCommandExecutionProperties);

	STDMETHOD(UpdateProperty)(UINT nCmdID,
		__in REFPROPERTYKEY key,
		__in_opt const PROPVARIANT* ppropvarCurrentValue,
		__out PROPVARIANT* ppropvarNewValue);


	
	STDMETHOD(InvalidateUICommand)(UINT32 commandId,
            UI_INVALIDATIONS flags,
            /* [annotation][in] */ 
            __in_opt  const PROPERTYKEY *key);
        

	STDMETHOD(GetUICommandProperty)(UINT32 commandId,
            /* [in] */ REFPROPERTYKEY key,
            /* [out] */ PROPVARIANT *value);

	STDMETHOD(SetUICommandProperty)(UINT32 commandId,
            /* [in] */ REFPROPERTYKEY key,
            /* [in] */ REFPROPVARIANT value);

	static void RegisterClass(HINSTANCE hInstance);

	CRibbonResultView();

	void SetRibbonInfo(const shared_ptr<CRibbonInfo> &ribbonInfo) { m_ribbonInfo = ribbonInfo;}
	HRESULT ShowContextualTab(int nCmdID, UI_CONTEXTAVAILABILITY UIContextAvailability);
	HRESULT ShowContextMenu(int nCmdID);
	HRESULT SetApplicationMode(INT32 applicationMode);
	void RegisterForCloseEvent(ICloseEvent *handler) { m_closeHandlers.push_back(handler); }
	void SetUseSetValues(bool bUse) { m_bUseSetValues = bUse; }
	void SetSetStringValue(const wstring &text) { m_setStringValue = text; }
	void SetSetNumericValue(double value) { m_setNumericValue = value; }
	void SetSetBooleanValue(bool value) { m_setBooleanValue = value; }
	virtual ~CRibbonResultView();
	HRESULT LoadState();
	HRESULT SaveState();

protected:
	STDMETHOD(OnAfterCreateRibbon)(HWND hWnd, HINSTANCE hInstance);
};
